<!DOCTYPE html>
<html lang="en-US">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="language" content="en" />
        <link href="./assets/ffd55088/css/bootstrap.css" rel="stylesheet">
<link href="./assets/5cf9384a/solarized_light.css" rel="stylesheet">
<link href="./assets/6c54116e/style.css" rel="stylesheet">
<script src="./assets/a44cef0f/jquery.js"></script>
<script src="./assets/ffd55088/js/bootstrap.js"></script>
<script src="./assets/8ac4e28a/jssearch.js"></script>    <title>Models - Application Structure - The Definitive Guide to Yii 2.0</title>
</head>
<body>

<div class="wrap">
    <nav id="w1061" class="navbar-inverse navbar-fixed-top navbar" role="navigation"><div class="navbar-header"><button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#w1061-collapse"><span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span></button><a class="navbar-brand" href="./index.html">The Definitive Guide to Yii 2.0</a></div><div id="w1061-collapse" class="collapse navbar-collapse"><ul id="w1062" class="navbar-nav nav"><li><a href="./index.html">Class reference</a></li>
<li class="dropdown"><a class="dropdown-toggle" href="#" data-toggle="dropdown">Extensions <b class="caret"></b></a><ul id="w1063" class="dropdown-menu"><li><a href="./ext-apidoc-index.html" tabindex="-1">apidoc</a></li>
<li><a href="./ext-authclient-index.html" tabindex="-1">authclient</a></li>
<li><a href="./ext-bootstrap-index.html" tabindex="-1">bootstrap</a></li>
<li><a href="./ext-codeception-index.html" tabindex="-1">codeception</a></li>
<li><a href="./ext-debug-index.html" tabindex="-1">debug</a></li>
<li><a href="./ext-elasticsearch-index.html" tabindex="-1">elasticsearch</a></li>
<li><a href="./ext-faker-index.html" tabindex="-1">faker</a></li>
<li><a href="./ext-gii-index.html" tabindex="-1">gii</a></li>
<li><a href="./ext-imagine-index.html" tabindex="-1">imagine</a></li>
<li><a href="./ext-jui-index.html" tabindex="-1">jui</a></li>
<li><a href="./ext-mongodb-index.html" tabindex="-1">mongodb</a></li>
<li><a href="./ext-redis-index.html" tabindex="-1">redis</a></li>
<li><a href="./ext-smarty-index.html" tabindex="-1">smarty</a></li>
<li><a href="./ext-sphinx-index.html" tabindex="-1">sphinx</a></li>
<li><a href="./ext-swiftmailer-index.html" tabindex="-1">swiftmailer</a></li>
<li><a href="./ext-twig-index.html" tabindex="-1">twig</a></li></ul></li>
<li><a href="./guide-README.html">Guide</a></li></ul><div class="navbar-form navbar-left" role="search">
  <div class="form-group">
    <input id="searchbox" type="text" class="form-control" placeholder="Search">
  </div>
</div>
</div></nav>
    <div id="search-resultbox" style="display: none;" class="modal-content">
        <ul id="search-results">
        </ul>
    </div>

    
<div class="row">
    <div class="col-md-2">
                <div id="navigation" class="list-group"><a class="list-group-item" href="#navigation-1045" data-toggle="collapse" data-parent="#navigation">Introduction <b class="caret"></b></a><div id="navigation-1045" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-intro-yii.html">About Yii</a>
<a class="list-group-item" href="./guide-intro-upgrade-from-v1.html">Upgrading from Version 1.1</a></div>
<a class="list-group-item" href="#navigation-1046" data-toggle="collapse" data-parent="#navigation">Getting Started <b class="caret"></b></a><div id="navigation-1046" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-start-installation.html">Installing Yii</a>
<a class="list-group-item" href="./guide-start-workflow.html">Running Applications</a>
<a class="list-group-item" href="./guide-start-hello.html">Saying Hello</a>
<a class="list-group-item" href="./guide-start-forms.html">Working with Forms</a>
<a class="list-group-item" href="./guide-start-databases.html">Working with Databases</a>
<a class="list-group-item" href="./guide-start-gii.html">Generating Code with Gii</a>
<a class="list-group-item" href="./guide-start-looking-ahead.html">Looking Ahead</a></div>
<a class="list-group-item active" href="#navigation-1047" data-toggle="collapse" data-parent="#navigation">Application Structure <b class="caret"></b></a><div id="navigation-1047" class="submenu panel-collapse collapse in"><a class="list-group-item" href="./guide-structure-overview.html">Overview</a>
<a class="list-group-item" href="./guide-structure-entry-scripts.html">Entry Scripts</a>
<a class="list-group-item" href="./guide-structure-applications.html">Applications</a>
<a class="list-group-item" href="./guide-structure-application-components.html">Application Components</a>
<a class="list-group-item" href="./guide-structure-controllers.html">Controllers</a>
<a class="list-group-item active" href="./guide-structure-models.html">Models</a>
<a class="list-group-item" href="./guide-structure-views.html">Views</a>
<a class="list-group-item" href="./guide-structure-modules.html">Modules</a>
<a class="list-group-item" href="./guide-structure-filters.html">Filters</a>
<a class="list-group-item" href="./guide-structure-widgets.html">Widgets</a>
<a class="list-group-item" href="./guide-structure-assets.html">Assets</a>
<a class="list-group-item" href="./guide-structure-extensions.html">Extensions</a></div>
<a class="list-group-item" href="#navigation-1048" data-toggle="collapse" data-parent="#navigation">Handling Requests <b class="caret"></b></a><div id="navigation-1048" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-runtime-overview.html">Overview</a>
<a class="list-group-item" href="./guide-runtime-bootstrapping.html">Bootstrapping</a>
<a class="list-group-item" href="./guide-runtime-routing.html">Routing and URL Creation</a>
<a class="list-group-item" href="./guide-runtime-requests.html">Requests</a>
<a class="list-group-item" href="./guide-runtime-responses.html">Responses</a>
<a class="list-group-item" href="./guide-runtime-sessions-cookies.html">Sessions and Cookies</a>
<a class="list-group-item" href="./guide-runtime-handling-errors.html">Handling Errors</a>
<a class="list-group-item" href="./guide-runtime-logging.html">Logging</a></div>
<a class="list-group-item" href="#navigation-1049" data-toggle="collapse" data-parent="#navigation">Key Concepts <b class="caret"></b></a><div id="navigation-1049" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-concept-components.html">Components</a>
<a class="list-group-item" href="./guide-concept-properties.html">Properties</a>
<a class="list-group-item" href="./guide-concept-events.html">Events</a>
<a class="list-group-item" href="./guide-concept-behaviors.html">Behaviors</a>
<a class="list-group-item" href="./guide-concept-configurations.html">Configurations</a>
<a class="list-group-item" href="./guide-concept-aliases.html">Aliases</a>
<a class="list-group-item" href="./guide-concept-autoloading.html">Class Autoloading</a>
<a class="list-group-item" href="./guide-concept-service-locator.html">Service Locator</a>
<a class="list-group-item" href="./guide-concept-di-container.html">Dependency Injection Container</a></div>
<a class="list-group-item" href="#navigation-1050" data-toggle="collapse" data-parent="#navigation">Working with Databases <b class="caret"></b></a><div id="navigation-1050" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-db-dao.html">Data Access Objects</a>
<a class="list-group-item" href="./guide-db-query-builder.html">Query Builder</a>
<a class="list-group-item" href="./guide-db-active-record.html">Active Record</a>
<a class="list-group-item" href="./guide-db-migrations.html">Migrations</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-sphinx/blob/master/docs/guide/README.md">Sphinx</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-redis/blob/master/docs/guide/README.md">Redis</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-mongodb/blob/master/docs/guide/README.md">MongoDB</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-elasticsearch/blob/master/docs/guide/README.md">ElasticSearch</a></div>
<a class="list-group-item" href="#navigation-1051" data-toggle="collapse" data-parent="#navigation">Getting Data from Users <b class="caret"></b></a><div id="navigation-1051" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-input-forms.html">Creating Forms</a>
<a class="list-group-item" href="./guide-input-validation.html">Validating Input</a>
<a class="list-group-item" href="./guide-input-file-upload.html">Uploading Files</a>
<a class="list-group-item" href="./guide-input-tabular-input.html">Collecting Tabular Input</a>
<a class="list-group-item" href="./guide-input-multiple-models.html">Getting Data for Multiple Models</a></div>
<a class="list-group-item" href="#navigation-1052" data-toggle="collapse" data-parent="#navigation">Displaying Data <b class="caret"></b></a><div id="navigation-1052" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-output-formatting.html">Data Formatting</a>
<a class="list-group-item" href="./guide-output-pagination.html">Pagination</a>
<a class="list-group-item" href="./guide-output-sorting.html">Sorting</a>
<a class="list-group-item" href="./guide-output-data-providers.html">Data Providers</a>
<a class="list-group-item" href="./guide-output-data-widgets.html">Data Widgets</a>
<a class="list-group-item" href="./guide-output-client-scripts.html">Working with Client Scripts</a>
<a class="list-group-item" href="./guide-output-theming.html">Theming</a></div>
<a class="list-group-item" href="#navigation-1053" data-toggle="collapse" data-parent="#navigation">Security <b class="caret"></b></a><div id="navigation-1053" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-security-overview.html">Overview</a>
<a class="list-group-item" href="./guide-security-authentication.html">Authentication</a>
<a class="list-group-item" href="./guide-security-authorization.html">Authorization</a>
<a class="list-group-item" href="./guide-security-passwords.html">Working with Passwords</a>
<a class="list-group-item" href="./guide-security-cryptography.html">Cryptography</a>
<a class="list-group-item" href="./guide-structure-views.html#security">Views security</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-authclient/blob/master/docs/guide/README.md">Auth Clients</a>
<a class="list-group-item" href="./guide-security-best-practices.html">Best Practices</a></div>
<a class="list-group-item" href="#navigation-1054" data-toggle="collapse" data-parent="#navigation">Caching <b class="caret"></b></a><div id="navigation-1054" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-caching-overview.html">Overview</a>
<a class="list-group-item" href="./guide-caching-data.html">Data Caching</a>
<a class="list-group-item" href="./guide-caching-fragment.html">Fragment Caching</a>
<a class="list-group-item" href="./guide-caching-page.html">Page Caching</a>
<a class="list-group-item" href="./guide-caching-http.html">HTTP Caching</a></div>
<a class="list-group-item" href="#navigation-1055" data-toggle="collapse" data-parent="#navigation">RESTful Web Services <b class="caret"></b></a><div id="navigation-1055" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-rest-quick-start.html">Quick Start</a>
<a class="list-group-item" href="./guide-rest-resources.html">Resources</a>
<a class="list-group-item" href="./guide-rest-controllers.html">Controllers</a>
<a class="list-group-item" href="./guide-rest-routing.html">Routing</a>
<a class="list-group-item" href="./guide-rest-response-formatting.html">Response Formatting</a>
<a class="list-group-item" href="./guide-rest-authentication.html">Authentication</a>
<a class="list-group-item" href="./guide-rest-rate-limiting.html">Rate Limiting</a>
<a class="list-group-item" href="./guide-rest-versioning.html">Versioning</a>
<a class="list-group-item" href="./guide-rest-error-handling.html">Error Handling</a></div>
<a class="list-group-item" href="#navigation-1056" data-toggle="collapse" data-parent="#navigation">Development Tools <b class="caret"></b></a><div id="navigation-1056" class="submenu panel-collapse collapse"><a class="list-group-item" href="https://github.com/yiisoft/yii2-debug/blob/master/docs/guide/README.md">Debug Toolbar and Debugger</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-gii/blob/master/docs/guide/README.md">Generating Code using Gii</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-apidoc">Generating API Documentation</a></div>
<a class="list-group-item" href="#navigation-1057" data-toggle="collapse" data-parent="#navigation">Testing <b class="caret"></b></a><div id="navigation-1057" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-test-overview.html">Overview</a>
<a class="list-group-item" href="./guide-test-environment-setup.html">Testing environment setup</a>
<a class="list-group-item" href="./guide-test-unit.html">Unit Tests</a>
<a class="list-group-item" href="./guide-test-functional.html">Functional Tests</a>
<a class="list-group-item" href="./guide-test-acceptance.html">Acceptance Tests</a>
<a class="list-group-item" href="./guide-test-fixtures.html">Fixtures</a></div>
<a class="list-group-item" href="#navigation-1058" data-toggle="collapse" data-parent="#navigation">Special Topics <b class="caret"></b></a><div id="navigation-1058" class="submenu panel-collapse collapse"><a class="list-group-item" href="https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md">Advanced Project Template</a>
<a class="list-group-item" href="./guide-tutorial-start-from-scratch.html">Building Application from Scratch</a>
<a class="list-group-item" href="./guide-tutorial-console.html">Console Commands</a>
<a class="list-group-item" href="./guide-tutorial-core-validators.html">Core Validators</a>
<a class="list-group-item" href="./guide-tutorial-i18n.html">Internationalization</a>
<a class="list-group-item" href="./guide-tutorial-mailing.html">Mailing</a>
<a class="list-group-item" href="./guide-tutorial-performance-tuning.html">Performance Tuning</a>
<a class="list-group-item" href="./guide-tutorial-shared-hosting.html">Shared Hosting Environment</a>
<a class="list-group-item" href="./guide-tutorial-template-engines.html">Template Engines</a>
<a class="list-group-item" href="./guide-tutorial-yii-integration.html">Working with Third-Party Code</a></div>
<a class="list-group-item" href="#navigation-1059" data-toggle="collapse" data-parent="#navigation">Widgets <b class="caret"></b></a><div id="navigation-1059" class="submenu panel-collapse collapse"><a class="list-group-item" href="https://github.com/yiisoft/yii2-bootstrap/blob/master/docs/guide/README.md">Bootstrap Widgets</a>
<a class="list-group-item" href="https://github.com/yiisoft/yii2-jui/blob/master/docs/guide/README.md">jQuery UI Widgets</a></div>
<a class="list-group-item" href="#navigation-1060" data-toggle="collapse" data-parent="#navigation">Helpers <b class="caret"></b></a><div id="navigation-1060" class="submenu panel-collapse collapse"><a class="list-group-item" href="./guide-helper-overview.html">Overview</a>
<a class="list-group-item" href="./guide-helper-array.html">ArrayHelper</a>
<a class="list-group-item" href="./guide-helper-html.html">Html</a>
<a class="list-group-item" href="./guide-helper-url.html">Url</a></div></div>    </div>
    <div class="col-md-9 guide-content" role="main">
        <h1>Models <span id="models"></span><a href="#models" class="hashlink">&para;</a></h1>
<div class="toc"><ol><li><a href="#attributes">Attributes</a></li>
<li><a href="#scenarios">Scenarios</a></li>
<li><a href="#validation-rules">Validation Rules</a></li>
<li><a href="#massive-assignment">Massive Assignment</a></li>
<li><a href="#data-exporting">Data Exporting</a></li>
<li><a href="#best-practices">Best Practices</a></li></ol></div>
<p>Models are part of the <a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">MVC</a> architecture.
They are objects representing business data, rules and logic.</p>
<p>You can create model classes by extending <a href="./yii-base-model.html">yii\base\Model</a> or its child classes. The base class
<a href="./yii-base-model.html">yii\base\Model</a> supports many useful features:</p>
<ul>
<li><a href="#attributes">Attributes</a>: represent the business data and can be accessed like normal object properties
or array elements;</li>
<li><a href="#attribute-labels">Attribute labels</a>: specify the display labels for attributes;</li>
<li><a href="#massive-assignment">Massive assignment</a>: supports populating multiple attributes in a single step;</li>
<li><a href="#validation-rules">Validation rules</a>: ensures input data based on the declared validation rules;</li>
<li><a href="#data-exporting">Data Exporting</a>: allows model data to be exported in terms of arrays with customizable formats.</li>
</ul>
<p>The <code>Model</code> class is also the base class for more advanced models, such as <a href="guide-db-active-record.html">Active Record</a>.
Please refer to the relevant documentation for more details about these advanced models.</p>
<blockquote class="info"><p><strong>Info: </strong>You are not required to base your model classes on <a href="./yii-base-model.html">yii\base\Model</a>. However, because there are many Yii
  components built to support <a href="./yii-base-model.html">yii\base\Model</a>, it is usually the preferable base class for a model.</p>
</blockquote>
<h2>Attributes  <span id="attributes"></span><a href="#attributes" class="hashlink">&para;</a></h2><p>Models represent business data in terms of <em>attributes</em>. Each attribute is like a publicly accessible property
of a model. The method <a href="./yii-base-model.html#attributes()-detail">yii\base\Model::attributes()</a> specifies what attributes a model class has.</p>
<p>You can access an attribute like accessing a normal object property:</p>
<pre><code class="hljs php language-php"><span class="hljs-variable">$model</span> = <span class="hljs-keyword">new</span> \app\models\ContactForm;

<span class="hljs-comment">// "name" is an attribute of ContactForm</span>
<span class="hljs-variable">$model</span>-&gt;name = <span class="hljs-string">'example'</span>;
<span class="hljs-keyword">echo</span> <span class="hljs-variable">$model</span>-&gt;name;
</code></pre>
<p>You can also access attributes like accessing array elements, thanks to the support for
<a href="http://php.net/manual/en/class.arrayaccess.php">ArrayAccess</a> and <a href="http://php.net/manual/en/class.arrayiterator.php">ArrayIterator</a>
by <a href="./yii-base-model.html">yii\base\Model</a>:</p>
<pre><code class="hljs php language-php"><span class="hljs-variable">$model</span> = <span class="hljs-keyword">new</span> \app\models\ContactForm;

<span class="hljs-comment">// accessing attributes like array elements</span>
<span class="hljs-variable">$model</span>[<span class="hljs-string">'name'</span>] = <span class="hljs-string">'example'</span>;
<span class="hljs-keyword">echo</span> <span class="hljs-variable">$model</span>[<span class="hljs-string">'name'</span>];

<span class="hljs-comment">// iterate attributes</span>
<span class="hljs-keyword">foreach</span> (<span class="hljs-variable">$model</span> <span class="hljs-keyword">as</span> <span class="hljs-variable">$name</span> =&gt; <span class="hljs-variable">$value</span>) {
    <span class="hljs-keyword">echo</span> <span class="hljs-string">"$name: $value\n"</span>;
}
</code></pre>
<h3>Defining Attributes  <span id="defining-attributes"></span><a href="#defining-attributes" class="hashlink">&para;</a></h3><p>By default, if your model class extends directly from <a href="./yii-base-model.html">yii\base\Model</a>, all its <em>non-static public</em> member
variables are attributes. For example, the <code>ContactForm</code> model class below has four attributes: <code>name</code>, <code>email</code>,
<code>subject</code> and <code>body</code>. The <code>ContactForm</code> model is used to represent the input data received from an HTML form.</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">namespace</span> <span class="hljs-title">app</span>\<span class="hljs-title">models</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">base</span>\<span class="hljs-title">Model</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ContactForm</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Model</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-variable">$name</span>;
    <span class="hljs-keyword">public</span> <span class="hljs-variable">$email</span>;
    <span class="hljs-keyword">public</span> <span class="hljs-variable">$subject</span>;
    <span class="hljs-keyword">public</span> <span class="hljs-variable">$body</span>;
}
</code></pre>
<p>You may override <a href="./yii-base-model.html#attributes()-detail">yii\base\Model::attributes()</a> to define attributes in a different way. The method should
return the names of the attributes in a model. For example, <a href="./yii-db-activerecord.html">yii\db\ActiveRecord</a> does so by returning
the column names of the associated database table as its attribute names. Note that you may also need to
override the magic methods such as <code>__get()</code>, <code>__set()</code> so that the attributes can be accessed like
normal object properties.</p>
<h3>Attribute Labels  <span id="attribute-labels"></span><a href="#attribute-labels" class="hashlink">&para;</a></h3><p>When displaying values or getting input for attributes, you often need to display some labels associated
with attributes. For example, given an attribute named <code>firstName</code>, you may want to display a label <code>First Name</code>
which is more user-friendly when displayed to end users in places such as form inputs and error messages.</p>
<p>You can get the label of an attribute by calling <a href="./yii-base-model.html#getAttributeLabel()-detail">yii\base\Model::getAttributeLabel()</a>. For example,</p>
<pre><code class="hljs php language-php"><span class="hljs-variable">$model</span> = <span class="hljs-keyword">new</span> \app\models\ContactForm;

<span class="hljs-comment">// displays "Name"</span>
<span class="hljs-keyword">echo</span> <span class="hljs-variable">$model</span>-&gt;getAttributeLabel(<span class="hljs-string">'name'</span>);
</code></pre>
<p>By default, attribute labels are automatically generated from attribute names. The generation is done by
the method <a href="./yii-base-model.html#generateAttributeLabel()-detail">yii\base\Model::generateAttributeLabel()</a>. It will turn camel-case variable names into
multiple words with the first letter in each word in upper case. For example, <code>username</code> becomes <code>Username</code>,
and <code>firstName</code> becomes <code>First Name</code>.</p>
<p>If you do not want to use automatically generated labels, you may override <a href="./yii-base-model.html#attributeLabels()-detail">yii\base\Model::attributeLabels()</a>
to explicitly declare attribute labels. For example,</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">namespace</span> <span class="hljs-title">app</span>\<span class="hljs-title">models</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">base</span>\<span class="hljs-title">Model</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ContactForm</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Model</span>
</span>{
    <span class="hljs-keyword">public</span> <span class="hljs-variable">$name</span>;
    <span class="hljs-keyword">public</span> <span class="hljs-variable">$email</span>;
    <span class="hljs-keyword">public</span> <span class="hljs-variable">$subject</span>;
    <span class="hljs-keyword">public</span> <span class="hljs-variable">$body</span>;

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">attributeLabels</span><span class="hljs-params">()</span>
    </span>{
        <span class="hljs-keyword">return</span> [
            <span class="hljs-string">'name'</span> =&gt; <span class="hljs-string">'Your name'</span>,
            <span class="hljs-string">'email'</span> =&gt; <span class="hljs-string">'Your email address'</span>,
            <span class="hljs-string">'subject'</span> =&gt; <span class="hljs-string">'Subject'</span>,
            <span class="hljs-string">'body'</span> =&gt; <span class="hljs-string">'Content'</span>,
        ];
    }
}
</code></pre>
<p>For applications supporting multiple languages, you may want to translate attribute labels. This can be done
in the <a href="./yii-base-model.html#attributeLabels()-detail">attributeLabels()</a> method as well, like the following:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">attributeLabels</span><span class="hljs-params">()</span>
</span>{
    <span class="hljs-keyword">return</span> [
        <span class="hljs-string">'name'</span> =&gt; \Yii::t(<span class="hljs-string">'app'</span>, <span class="hljs-string">'Your name'</span>),
        <span class="hljs-string">'email'</span> =&gt; \Yii::t(<span class="hljs-string">'app'</span>, <span class="hljs-string">'Your email address'</span>),
        <span class="hljs-string">'subject'</span> =&gt; \Yii::t(<span class="hljs-string">'app'</span>, <span class="hljs-string">'Subject'</span>),
        <span class="hljs-string">'body'</span> =&gt; \Yii::t(<span class="hljs-string">'app'</span>, <span class="hljs-string">'Content'</span>),
    ];
}
</code></pre>
<p>You may even conditionally define attribute labels. For example, based on the <a href="#scenarios">scenario</a> the model
is being used in, you may return different labels for the same attribute.</p>
<blockquote class="info"><p><strong>Info: </strong>Strictly speaking, attribute labels are part of <a href="guide-structure-views.html">views</a>. But declaring labels
  in models is often very convenient and can result in very clean and reusable code.</p>
</blockquote>
<h2>Scenarios  <span id="scenarios"></span><a href="#scenarios" class="hashlink">&para;</a></h2><p>A model may be used in different <em>scenarios</em>. For example, a <code>User</code> model may be used to collect user login inputs,
but it may also be used for the user registration purpose. In different scenarios, a model may use different
business rules and logic. For example, the <code>email</code> attribute may be required during user registration,
but not so during user login.</p>
<p>A model uses the <a href="./yii-base-model.html#$scenario-detail">yii\base\Model::$scenario</a> property to keep track of the scenario it is being used in.
By default, a model supports only a single scenario named <code>default</code>. The following code shows two ways of
setting the scenario of a model:</p>
<pre><code class="hljs php language-php"><span class="hljs-comment">// scenario is set as a property</span>
<span class="hljs-variable">$model</span> = <span class="hljs-keyword">new</span> User;
<span class="hljs-variable">$model</span>-&gt;scenario = User::SCENARIO_LOGIN;

<span class="hljs-comment">// scenario is set through configuration</span>
<span class="hljs-variable">$model</span> = <span class="hljs-keyword">new</span> User([<span class="hljs-string">'scenario'</span> =&gt; User::SCENARIO_LOGIN]);
</code></pre>
<p>By default, the scenarios supported by a model are determined by the <a href="#validation-rules">validation rules</a> declared
in the model. However, you can customize this behavior by overriding the <a href="./yii-base-model.html#scenarios()-detail">yii\base\Model::scenarios()</a> method,
like the following:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">namespace</span> <span class="hljs-title">app</span>\<span class="hljs-title">models</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">db</span>\<span class="hljs-title">ActiveRecord</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ActiveRecord</span>
</span>{
    <span class="hljs-keyword">const</span> SCENARIO_LOGIN = <span class="hljs-string">'login'</span>;
    <span class="hljs-keyword">const</span> SCENARIO_REGISTER = <span class="hljs-string">'register'</span>;

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">scenarios</span><span class="hljs-params">()</span>
    </span>{
        <span class="hljs-keyword">return</span> [
            <span class="hljs-keyword">self</span>::SCENARIO_LOGIN =&gt; [<span class="hljs-string">'username'</span>, <span class="hljs-string">'password'</span>],
            <span class="hljs-keyword">self</span>::SCENARIO_REGISTER =&gt; [<span class="hljs-string">'username'</span>, <span class="hljs-string">'email'</span>, <span class="hljs-string">'password'</span>],
        ];
    }
}
</code></pre>
<blockquote class="info"><p><strong>Info: </strong>In the above and following examples, the model classes are extending from <a href="./yii-db-activerecord.html">yii\db\ActiveRecord</a>
  because the usage of multiple scenarios usually happens to <a href="guide-db-active-record.html">Active Record</a> classes.</p>
</blockquote>
<p>The <code>scenarios()</code> method returns an array whose keys are the scenario names and values the corresponding
<em>active attributes</em>. An active attribute can be <a href="#massive-assignment">massively assigned</a> and is subject
to <a href="#validation-rules">validation</a>. In the above example, the <code>username</code> and <code>password</code> attributes are active
in the <code>login</code> scenario; while in the <code>register</code> scenario, <code>email</code> is also active besides <code>username</code> and <code>password</code>.</p>
<p>The default implementation of <code>scenarios()</code> will return all scenarios found in the validation rule declaration
method <a href="./yii-base-model.html#rules()-detail">yii\base\Model::rules()</a>. When overriding <code>scenarios()</code>, if you want to introduce new scenarios
in addition to the default ones, you may write code like the following:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">namespace</span> <span class="hljs-title">app</span>\<span class="hljs-title">models</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">yii</span>\<span class="hljs-title">db</span>\<span class="hljs-title">ActiveRecord</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">User</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ActiveRecord</span>
</span>{
    <span class="hljs-keyword">const</span> SCENARIO_LOGIN = <span class="hljs-string">'login'</span>;
    <span class="hljs-keyword">const</span> SCENARIO_REGISTER = <span class="hljs-string">'register'</span>;

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">scenarios</span><span class="hljs-params">()</span>
    </span>{
        <span class="hljs-variable">$scenarios</span> = <span class="hljs-keyword">parent</span>::scenarios();
        <span class="hljs-variable">$scenarios</span>[<span class="hljs-keyword">self</span>::SCENARIO_LOGIN] = [<span class="hljs-string">'username'</span>, <span class="hljs-string">'password'</span>];
        <span class="hljs-variable">$scenarios</span>[<span class="hljs-keyword">self</span>::SCENARIO_REGISTER] = [<span class="hljs-string">'username'</span>, <span class="hljs-string">'email'</span>, <span class="hljs-string">'password'</span>];
        <span class="hljs-keyword">return</span> <span class="hljs-variable">$scenarios</span>;
    }
}
</code></pre>
<p>The scenario feature is primarily used by <a href="#validation-rules">validation</a> and <a href="#massive-assignment">massive attribute assignment</a>.
You can, however, use it for other purposes. For example, you may declare <a href="#attribute-labels">attribute labels</a>
differently based on the current scenario.</p>
<h2>Validation Rules  <span id="validation-rules"></span><a href="#validation-rules" class="hashlink">&para;</a></h2><p>When the data for a model is received from end users, it should be validated to make sure it satisfies
certain rules (called <em>validation rules</em>, also known as <em>business rules</em>). For example, given a <code>ContactForm</code> model,
you may want to make sure all attributes are not empty and the <code>email</code> attribute contains a valid email address.
If the values for some attributes do not satisfy the corresponding business rules, appropriate error messages
should be displayed to help the user to fix the errors.</p>
<p>You may call <a href="./yii-base-model.html#validate()-detail">yii\base\Model::validate()</a> to validate the received data. The method will use
the validation rules declared in <a href="./yii-base-model.html#rules()-detail">yii\base\Model::rules()</a> to validate every relevant attribute. If no error
is found, it will return true. Otherwise, it will keep the errors in the <a href="./yii-base-model.html#$errors-detail">yii\base\Model::$errors</a> property
and return false. For example,</p>
<pre><code class="hljs php language-php"><span class="hljs-variable">$model</span> = <span class="hljs-keyword">new</span> \app\models\ContactForm;

<span class="hljs-comment">// populate model attributes with user inputs</span>
<span class="hljs-variable">$model</span>-&gt;attributes = \Yii::<span class="hljs-variable">$app</span>-&gt;request-&gt;post(<span class="hljs-string">'ContactForm'</span>);

<span class="hljs-keyword">if</span> (<span class="hljs-variable">$model</span>-&gt;validate()) {
    <span class="hljs-comment">// all inputs are valid</span>
} <span class="hljs-keyword">else</span> {
    <span class="hljs-comment">// validation failed: $errors is an array containing error messages</span>
    <span class="hljs-variable">$errors</span> = <span class="hljs-variable">$model</span>-&gt;errors;
}
</code></pre>
<p>To declare validation rules associated with a model, override the <a href="./yii-base-model.html#rules()-detail">yii\base\Model::rules()</a> method by returning
the rules that the model attributes should satisfy. The following example shows the validation rules declared
for the <code>ContactForm</code> model:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">rules</span><span class="hljs-params">()</span>
</span>{
    <span class="hljs-keyword">return</span> [
        <span class="hljs-comment">// the name, email, subject and body attributes are required</span>
        [[<span class="hljs-string">'name'</span>, <span class="hljs-string">'email'</span>, <span class="hljs-string">'subject'</span>, <span class="hljs-string">'body'</span>], <span class="hljs-string">'required'</span>],

        <span class="hljs-comment">// the email attribute should be a valid email address</span>
        [<span class="hljs-string">'email'</span>, <span class="hljs-string">'email'</span>],
    ];
}
</code></pre>
<p>A rule can be used to validate one or multiple attributes, and an attribute may be validated by one or multiple rules.
Please refer to the <a href="guide-input-validation.html">Validating Input</a> section for more details on how to declare
validation rules.</p>
<p>Sometimes, you may want a rule to be applied only in certain <a href="#scenarios">scenarios</a>. To do so, you can
specify the <code>on</code> property of a rule, like the following:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">rules</span><span class="hljs-params">()</span>
</span>{
    <span class="hljs-keyword">return</span> [
        <span class="hljs-comment">// username, email and password are all required in "register" scenario</span>
        [[<span class="hljs-string">'username'</span>, <span class="hljs-string">'email'</span>, <span class="hljs-string">'password'</span>], <span class="hljs-string">'required'</span>, <span class="hljs-string">'on'</span> =&gt; <span class="hljs-keyword">self</span>::SCENARIO_REGISTER],

        <span class="hljs-comment">// username and password are required in "login" scenario</span>
        [[<span class="hljs-string">'username'</span>, <span class="hljs-string">'password'</span>], <span class="hljs-string">'required'</span>, <span class="hljs-string">'on'</span> =&gt; <span class="hljs-keyword">self</span>::SCENARIO_LOGIN],
    ];
}
</code></pre>
<p>If you do not specify the <code>on</code> property, the rule would be applied in all scenarios. A rule is called
an <em>active rule</em> if it can be applied in the current <a href="./yii-base-model.html#$scenario-detail">scenario</a>.</p>
<p>An attribute will be validated if and only if it is an active attribute declared in <code>scenarios()</code> and
is associated with one or multiple active rules declared in <code>rules()</code>.</p>
<h2>Massive Assignment  <span id="massive-assignment"></span><a href="#massive-assignment" class="hashlink">&para;</a></h2><p>Massive assignment is a convenient way of populating a model with user inputs using a single line of code.
It populates the attributes of a model by assigning the input data directly to the <a href="./yii-base-model.html#$attributes-detail">yii\base\Model::$attributes</a>
property. The following two pieces of code are equivalent, both trying to assign the form data submitted by end users
to the attributes of the <code>ContactForm</code> model. Clearly, the former, which uses massive assignment, is much cleaner
and less error prone than the latter:</p>
<pre><code class="hljs php language-php"><span class="hljs-variable">$model</span> = <span class="hljs-keyword">new</span> \app\models\ContactForm;
<span class="hljs-variable">$model</span>-&gt;attributes = \Yii::<span class="hljs-variable">$app</span>-&gt;request-&gt;post(<span class="hljs-string">'ContactForm'</span>);
</code></pre>
<pre><code class="hljs php language-php"><span class="hljs-variable">$model</span> = <span class="hljs-keyword">new</span> \app\models\ContactForm;
<span class="hljs-variable">$data</span> = \Yii::<span class="hljs-variable">$app</span>-&gt;request-&gt;post(<span class="hljs-string">'ContactForm'</span>, []);
<span class="hljs-variable">$model</span>-&gt;name = <span class="hljs-keyword">isset</span>(<span class="hljs-variable">$data</span>[<span class="hljs-string">'name'</span>]) ? <span class="hljs-variable">$data</span>[<span class="hljs-string">'name'</span>] : <span class="hljs-keyword">null</span>;
<span class="hljs-variable">$model</span>-&gt;email = <span class="hljs-keyword">isset</span>(<span class="hljs-variable">$data</span>[<span class="hljs-string">'email'</span>]) ? <span class="hljs-variable">$data</span>[<span class="hljs-string">'email'</span>] : <span class="hljs-keyword">null</span>;
<span class="hljs-variable">$model</span>-&gt;subject = <span class="hljs-keyword">isset</span>(<span class="hljs-variable">$data</span>[<span class="hljs-string">'subject'</span>]) ? <span class="hljs-variable">$data</span>[<span class="hljs-string">'subject'</span>] : <span class="hljs-keyword">null</span>;
<span class="hljs-variable">$model</span>-&gt;body = <span class="hljs-keyword">isset</span>(<span class="hljs-variable">$data</span>[<span class="hljs-string">'body'</span>]) ? <span class="hljs-variable">$data</span>[<span class="hljs-string">'body'</span>] : <span class="hljs-keyword">null</span>;
</code></pre>
<h3>Safe Attributes  <span id="safe-attributes"></span><a href="#safe-attributes" class="hashlink">&para;</a></h3><p>Massive assignment only applies to the so-called <em>safe attributes</em> which are the attributes listed in
<a href="./yii-base-model.html#scenarios()-detail">yii\base\Model::scenarios()</a> for the current <a href="./yii-base-model.html#$scenario-detail">scenario</a> of a model.
For example, if the <code>User</code> model has the following scenario declaration, then when the current scenario
is <code>login</code>, only the <code>username</code> and <code>password</code> can be massively assigned. Any other attributes will
be kept untouched.</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">scenarios</span><span class="hljs-params">()</span>
</span>{
    <span class="hljs-keyword">return</span> [
        <span class="hljs-keyword">self</span>::SCENARIO_LOGIN =&gt; [<span class="hljs-string">'username'</span>, <span class="hljs-string">'password'</span>],
        <span class="hljs-keyword">self</span>::SCENARIO_REGISTER =&gt; [<span class="hljs-string">'username'</span>, <span class="hljs-string">'email'</span>, <span class="hljs-string">'password'</span>],
    ];
}
</code></pre>
<blockquote class="info"><p><strong>Info: </strong>The reason that massive assignment only applies to safe attributes is because you want to
  control which attributes can be modified by end user data. For example, if the <code>User</code> model
  has a <code>permission</code> attribute which determines the permission assigned to the user, you would
  like this attribute to be modifiable by administrators through a backend interface only.</p>
</blockquote>
<p>Because the default implementation of <a href="./yii-base-model.html#scenarios()-detail">yii\base\Model::scenarios()</a> will return all scenarios and attributes
found in <a href="./yii-base-model.html#rules()-detail">yii\base\Model::rules()</a>, if you do not override this method, it means an attribute is safe as long
as it appears in one of the active validation rules.</p>
<p>For this reason, a special validator aliased <code>safe</code> is provided so that you can declare an attribute
to be safe without actually validating it. For example, the following rules declare that both <code>title</code>
and <code>description</code> are safe attributes.</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">rules</span><span class="hljs-params">()</span>
</span>{
    <span class="hljs-keyword">return</span> [
        [[<span class="hljs-string">'title'</span>, <span class="hljs-string">'description'</span>], <span class="hljs-string">'safe'</span>],
    ];
}
</code></pre>
<h3>Unsafe Attributes  <span id="unsafe-attributes"></span><a href="#unsafe-attributes" class="hashlink">&para;</a></h3><p>As described above, the <a href="./yii-base-model.html#scenarios()-detail">yii\base\Model::scenarios()</a> method serves for two purposes: determining which attributes
should be validated, and determining which attributes are safe. In some rare cases, you may want to validate
an attribute but do not want to mark it safe. You can do so by prefixing an exclamation mark <code>!</code> to the attribute
name when declaring it in <code>scenarios()</code>, like the <code>secret</code> attribute in the following:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">scenarios</span><span class="hljs-params">()</span>
</span>{
    <span class="hljs-keyword">return</span> [
        <span class="hljs-keyword">self</span>::SCENARIO_LOGIN =&gt; [<span class="hljs-string">'username'</span>, <span class="hljs-string">'password'</span>, <span class="hljs-string">'!secret'</span>],
    ];
}
</code></pre>
<p>When the model is in the <code>login</code> scenario, all three attributes will be validated. However, only the <code>username</code>
and <code>password</code> attributes can be massively assigned. To assign an input value to the <code>secret</code> attribute, you
have to do it explicitly as follows,</p>
<pre><code class="hljs php language-php"><span class="hljs-variable">$model</span>-&gt;secret = <span class="hljs-variable">$secret</span>;
</code></pre>
<p>The same can be done in <code>rules()</code> method:</p>
<pre><code class="hljs php language-php"><span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">rules</span><span class="hljs-params">()</span>
</span>{
    <span class="hljs-keyword">return</span> [
        [[<span class="hljs-string">'username'</span>, <span class="hljs-string">'password'</span>, <span class="hljs-string">'!secret'</span>], <span class="hljs-string">'required'</span>, <span class="hljs-string">'on'</span> =&gt; <span class="hljs-string">'login'</span>]
    ];
}
</code></pre>
<p>In this case attributes <code>username</code>, <code>password</code> and <code>secret</code> are required, but <code>secret</code> must be assigned explicitly.</p>
<h2>Data Exporting  <span id="data-exporting"></span><a href="#data-exporting" class="hashlink">&para;</a></h2><p>Models often need to be exported in different formats. For example, you may want to convert a collection of
models into JSON or Excel format. The exporting process can be broken down into two independent steps.
In the first step, models are converted into arrays; in the second step, the arrays are converted into
target formats. You may just focus on the first step, because the second step can be achieved by generic
data formatters, such as <a href="./yii-web-jsonresponseformatter.html">yii\web\JsonResponseFormatter</a>.</p>
<p>The simplest way of converting a model into an array is to use the <a href="./yii-base-model.html#$attributes-detail">yii\base\Model::$attributes</a> property.
For example,</p>
<pre><code class="hljs php language-php"><span class="hljs-variable">$post</span> = \app\models\Post::findOne(<span class="hljs-number">100</span>);
<span class="hljs-variable">$array</span> = <span class="hljs-variable">$post</span>-&gt;attributes;
</code></pre>
<p>By default, the <a href="./yii-base-model.html#$attributes-detail">yii\base\Model::$attributes</a> property will return the values of <em>all</em> attributes
declared in <a href="./yii-base-model.html#attributes()-detail">yii\base\Model::attributes()</a>.</p>
<p>A more flexible and powerful way of converting a model into an array is to use the <a href="./yii-base-arrayabletrait.html#toArray()-detail">yii\base\Model::toArray()</a>
method. Its default behavior is the same as that of <a href="./yii-base-model.html#$attributes-detail">yii\base\Model::$attributes</a>. However, it allows you
to choose which data items, called <em>fields</em>, to be put in the resulting array and how they should be formatted.
In fact, it is the default way of exporting models in RESTful Web service development, as described in
the <a href="guide-rest-response-formatting.html">Response Formatting</a>.</p>
<h3>Fields  <span id="fields"></span><a href="#fields" class="hashlink">&para;</a></h3><p>A field is simply a named element in the array that is obtained by calling the <a href="./yii-base-arrayabletrait.html#toArray()-detail">yii\base\Model::toArray()</a> method
of a model.</p>
<p>By default, field names are equivalent to attribute names. However, you can change this behavior by overriding
the <a href="./yii-base-model.html#fields()-detail">fields()</a> and/or <a href="./yii-base-arrayabletrait.html#extraFields()-detail">extraFields()</a> methods. Both methods
should return a list of field definitions. The fields defined by <code>fields()</code> are default fields, meaning that
<code>toArray()</code> will return these fields by default. The <code>extraFields()</code> method defines additionally available fields
which can also be returned by <code>toArray()</code> as long as you specify them via the <code>$expand</code> parameter. For example,
the following code will return all fields defined in <code>fields()</code> and the <code>prettyName</code> and <code>fullAddress</code> fields
if they are defined in <code>extraFields()</code>.</p>
<pre><code class="hljs php language-php"><span class="hljs-variable">$array</span> = <span class="hljs-variable">$model</span>-&gt;toArray([], [<span class="hljs-string">'prettyName'</span>, <span class="hljs-string">'fullAddress'</span>]);
</code></pre>
<p>You can override <code>fields()</code> to add, remove, rename or redefine fields. The return value of <code>fields()</code>
should be an array. The array keys are the field names, and the array values are the corresponding
field definitions which can be either property/attribute names or anonymous functions returning the
corresponding field values. In the special case when a field name is the same as its defining attribute
name, you can omit the array key. For example,</p>
<pre><code class="hljs php language-php"><span class="hljs-comment">// explicitly list every field, best used when you want to make sure the changes</span>
<span class="hljs-comment">// in your DB table or model attributes do not cause your field changes (to keep API backward compatibility).</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fields</span><span class="hljs-params">()</span>
</span>{
    <span class="hljs-keyword">return</span> [
        <span class="hljs-comment">// field name is the same as the attribute name</span>
        <span class="hljs-string">'id'</span>,

        <span class="hljs-comment">// field name is "email", the corresponding attribute name is "email_address"</span>
        <span class="hljs-string">'email'</span> =&gt; <span class="hljs-string">'email_address'</span>,

        <span class="hljs-comment">// field name is "name", its value is defined by a PHP callback</span>
        <span class="hljs-string">'name'</span> =&gt; <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-params">()</span> </span>{
            <span class="hljs-keyword">return</span> <span class="hljs-variable">$this</span>-&gt;first_name . <span class="hljs-string">' '</span> . <span class="hljs-variable">$this</span>-&gt;last_name;
        },
    ];
}

<span class="hljs-comment">// filter out some fields, best used when you want to inherit the parent implementation</span>
<span class="hljs-comment">// and blacklist some sensitive fields.</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fields</span><span class="hljs-params">()</span>
</span>{
    <span class="hljs-variable">$fields</span> = <span class="hljs-keyword">parent</span>::fields();

    <span class="hljs-comment">// remove fields that contain sensitive information</span>
    <span class="hljs-keyword">unset</span>(<span class="hljs-variable">$fields</span>[<span class="hljs-string">'auth_key'</span>], <span class="hljs-variable">$fields</span>[<span class="hljs-string">'password_hash'</span>], <span class="hljs-variable">$fields</span>[<span class="hljs-string">'password_reset_token'</span>]);

    <span class="hljs-keyword">return</span> <span class="hljs-variable">$fields</span>;
}
</code></pre>
<blockquote class="warning"><p><strong>Warning: </strong>Because by default all attributes of a model will be included in the exported array, you should
examine your data to make sure they do not contain sensitive information. If there is such information,
you should override <code>fields()</code> to filter them out. In the above example, we choose
to filter out <code>auth_key</code>, <code>password_hash</code> and <code>password_reset_token</code>.</p>
</blockquote>
<h2>Best Practices  <span id="best-practices"></span><a href="#best-practices" class="hashlink">&para;</a></h2><p>Models are the central places to represent business data, rules and logic. They often need to be reused
in different places. In a well-designed application, models are usually much fatter than
<a href="guide-structure-controllers.html">controllers</a>.</p>
<p>In summary, models</p>
<ul>
<li>may contain attributes to represent business data;</li>
<li>may contain validation rules to ensure the data validity and integrity;</li>
<li>may contain methods implementing business logic;</li>
<li>should NOT directly access request, session, or any other environmental data. These data should be injected
by <a href="guide-structure-controllers.html">controllers</a> into models;</li>
<li>should avoid embedding HTML or other presentational code - this is better done in <a href="guide-structure-views.html">views</a>;</li>
<li>avoid having too many <a href="#scenarios">scenarios</a> in a single model.</li>
</ul>
<p>You may usually consider the last recommendation above when you are developing large complex systems.
In these systems, models could be very fat because they are used in many places and may thus contain many sets
of rules and business logic. This often ends up in a nightmare in maintaining the model code
because a single touch of the code could affect several different places. To make the model code more maintainable,
you may take the following strategy:</p>
<ul>
<li>Define a set of base model classes that are shared by different <a href="guide-structure-applications.html">applications</a> or
<a href="guide-structure-modules.html">modules</a>. These model classes should contain minimal sets of rules and logic that
are common among all their usages.</li>
<li>In each <a href="guide-structure-applications.html">application</a> or <a href="guide-structure-modules.html">module</a> that uses a model,
define a concrete model class by extending from the corresponding base model class. The concrete model classes
should contain rules and logic that are specific for that application or module.</li>
</ul>
<p>For example, in the <a href="https://github.com/yiisoft/yii2-app-advanced/blob/master/docs/guide/README.md">Advanced Project Template</a>, you may define a base model
class <code>common\models\Post</code>. Then for the front end application, you define and use a concrete model class
<code>frontend\models\Post</code> which extends from <code>common\models\Post</code>. And similarly for the back end application,
you define <code>backend\models\Post</code>. With this strategy, you will be sure that the code in <code>frontend\models\Post</code>
is only specific to the front end application, and if you make any change to it, you do not need to worry if
the change may break the back end application.</p>
        <div class="toplink"><a href="#" class="h1" title="go to top"><span class="glyphicon glyphicon-arrow-up"></a></div>
    </div>
</div>


</div>

<footer class="footer">
        <p class="pull-right"><small>Page generated on Sat, 09 Jul 2016 12:16:29 +0000</small></p>
    Powered by <a href="http://www.yiiframework.com/" rel="external">Yii Framework</a></footer>

<script type="text/javascript">jQuery(document).ready(function () {
    var shiftWindow = function () { scrollBy(0, -50) };
    if (location.hash) setTimeout(shiftWindow, 1);
    window.addEventListener("hashchange", shiftWindow);
var element = document.createElement("script");
element.src = "./jssearch.index.js";
document.body.appendChild(element);

var searchBox = $('#searchbox');

// search when typing in search field
searchBox.on("keyup", function(event) {
    var query = $(this).val();

    if (query == '' || event.which == 27) {
        $('#search-resultbox').hide();
        return;
    } else if (event.which == 13) {
        var selectedLink = $('#search-resultbox a.selected');
        if (selectedLink.length != 0) {
            document.location = selectedLink.attr('href');
            return;
        }
    } else if (event.which == 38 || event.which == 40) {
        $('#search-resultbox').show();

        var selected = $('#search-resultbox a.selected');
        if (selected.length == 0) {
            $('#search-results').find('a').first().addClass('selected');
        } else {
            var next;
            if (event.which == 40) {
                next = selected.parent().next().find('a').first();
            } else {
                next = selected.parent().prev().find('a').first();
            }
            if (next.length != 0) {
                var resultbox = $('#search-results');
                var position = next.position();

//              TODO scrolling is buggy and jumps around
//                resultbox.scrollTop(Math.floor(position.top));
//                console.log(position.top);

                selected.removeClass('selected');
                next.addClass('selected');
            }
        }

        return;
    }
    $('#search-resultbox').show();
    $('#search-results').html('<li><span class="no-results">No results</span></li>');

    var result = jssearch.search(query);

    if (result.length > 0) {
        var i = 0;
        var resHtml = '';

        for (var key in result) {
            if (i++ > 20) {
                break;
            }
            resHtml = resHtml +
            '<li><a href="' + result[key].file.u.substr(3) +'"><span class="title">' + result[key].file.t + '</span>' +
            '<span class="description">' + result[key].file.d + '</span></a></li>';
        }
        $('#search-results').html(resHtml);
    }
});

// hide the search results on ESC
$(document).on("keyup", function(event) { if (event.which == 27) { $('#search-resultbox').hide(); } });
// hide search results on click to document
$(document).bind('click', function (e) { $('#search-resultbox').hide(); });
// except the following:
searchBox.bind('click', function(e) { e.stopPropagation(); });
$('#search-resultbox').bind('click', function(e) { e.stopPropagation(); });

});</script></body>
</html>
